#define __Context_h_

#include "gl.h"
#include <stdio.h>
#include "zBuffer.h"

typedef struct{
	GLfloat x;
	GLfloat y;
	GLfloat z;
	GLfloat t;
} Vect4D;

typedef struct{
	GLfloat x;
	GLfloat y;
	GLfloat z;
}Vect3D;

typedef struct{
	GLfloat red;
	GLfloat green;
	GLfloat blue;
	GLfloat alpha;
}Color;

typedef struct{
	GLfloat x;
	GLfloat y;
	GLfloat z;
}Normal;

typedef struct{
	GLfloat s;
	GLfloat t;
	GLfloat r;
	GLfloat q;
}TextureCoords;

typedef struct{
	GLvoid * pointer;
	Vect4D	EyeCoord[GL_MAX_TEXTURE_UNITS + 4];
	Vect4D	ClipCoord[GL_MAX_TEXTURE_UNITS + 4];
	Vect3D	NDCoord[GL_MAX_TEXTURE_UNITS + 4];
	Vect3D	WindowCoord[GL_MAX_TEXTURE_UNITS + 4];
	GLenum 	type;
	GLsizei	stride;
	GLint		size;
}VertexArray;

typedef struct{
	GLfloat * pointer;
	GLenum	type;
	GLsizei	stride;
}NormalArray;

typedef struct{
	GLvoid * pointer;
	GLenum	type;
	GLsizei 	stride;
	GLint		size;
}ColorArray;

typedef struct{
	GLfloat * pointer;
	GLenum 	type;
	GLsizei	stride;
	GLint		size;
}PointSizePointer;

typedef struct{
	GLfloat * pointer;
	GLenum 	type;
	GLsizei	stride;
	GLint		size;
}TexCoordPointer;

typedef struct{
	GLsizei	px;	//width
	GLsizei	py;	//height
	GLint		ox;	//center point x
	GLint		oy;	//center point y
}ViewPort;

typedef struct{
	GLclampf zNear;
	GLclampf zFar;
}DepthRange;

typedef struct{
	GLfloat	_11;
	GLfloat	_12;
	GLfloat	_13;
	GLfloat	_14;
	GLfloat	_21;
	GLfloat	_22;
	GLfloat	_23;
	GLfloat	_24;
	GLfloat	_31;
	GLfloat	_32;
	GLfloat	_33;
	GLfloat	_34;
	GLfloat	_41;
	GLfloat	_42;
	GLfloat	_43;
	GLfloat	_44;
}Matrix4x4;


typedef struct{
	//Initially each stack has one matrix, and it is identity matrix, each stack pointer point to zero 
	
	Matrix4x4 * pCurrentMatrix;

	GLenum		CurrentMatrixMode;				//Current matrix mode indicator, value can be GL_PROJECTION,GL_TEXTURE,GL_MODELVIEW, initial mode is GL_MODELVIEW
	Matrix4x4	ProjectionStack[GL_MAX_PROJECTION_STACK_DEPTH ];
	GLint			ProjectionStackPointer;
	Matrix4x4	TextureStack[GL_MAX_TEXTURE_UNITS][GL_MAX_TEXTURE_STACK_DEPTH];
	GLint			TextureStackPointer[GL_MAX_TEXTURE_UNITS];
	Matrix4x4	ModelViewStack[GL_MAX_MODELVIEW_STACK_DEPTH];
	GLint			ModelViewStackPointer;
	GLfloat	   IdentityMatrix[16];
}Matrix;

typedef struct{
	GLfloat		p1;
	GLfloat		p2;
	GLfloat		p3;
	GLfloat		p4;
}ClipPlane;

typedef struct{
	GLboolean	PointSmooth;
	GLboolean	LineSmooth;
	GLboolean	ScissorTest;
	GLboolean	ColorMaterial;
	GLboolean	Normalize;
	GLboolean	RescaleNormal;
	GLboolean	PolygonOffsetFill;
	GLboolean	VertexArray;
	GLboolean	NormalArray;
	GLboolean	ColorArray;
	GLboolean	TextureCoordArray;
	GLboolean	MultiSample;
	GLboolean	SampleAlphaToCoverage;
	GLboolean	SampleAlphaToOne;
	GLboolean	SampleCoverage;
	GLboolean	Lighting;
	GLboolean	ClipPlane[GL_MAX_CLIP_PLANES];
	GLboolean	Light[GL_MAX_LIGHTS];
}glState;

typedef struct{
	Color 	Color;
	Normal	Normal;
	GLenum	ClientActiveTexture;				//Active texture selector
	GLenum	ActiveTexture;
	TextureCoords TextureCoords[GL_MAX_TEXTURE_UNITS];
	VertexArray VertexArray;
	NormalArray NormalArray;
	ColorArray	ColorArray;
	PointSizePointer PointSizePointer;
	TexCoordPointer TexCoordPointer;

	glState		State;
	
	GLboolean	TexCoordArrayEnabled[GL_MAX_TEXTURE_UNITS];
	GLboolean	ColorArrayEnabled;
	GLboolean	NormalArrayEnabled;
	GLboolean	VertexArrayEnabled;
	GLboolean	PointSizeArrayEnabled;

	ViewPort	ViewPort;
	DepthRange	DepthRange;
	Matrix		Matrix;
	ClipPlane	ClipPlane[5];
	GLfloat		PointSize;
        GLfloat         zBuffer[240][320];
}Context;


IMPORT void RecordError(GLenum error);
IMPORT void MatrixInit();
IMPORT void MatrixCopy(Matrix4x4 *, GLvoid *);
IMPORT void MatrixImport(GLfloat * m);
IMPORT void MatrixImportM(GLfloat * m);
IMPORT void MatrixMultiply(Matrix4x4 *,Vect4D *,Vect4D *);
IMPORT void ToggleState(GLenum, GLboolean);
IMPORT void Transform ( GLint);
IMPORT void PerspectiveDevise(Vect4D *, Vect3D *);
IMPORT void ViewportTransform(Vect3D *, Vect3D *);


//Rasterizer function:
IMPORT void DrawPoint(GLint index);
IMPORT void DrawLine(GLint from, GLint to);
IMPORT void DrawTriangle(GLint first);
//IMPORT GLboolean isVisible(GLint x, GLint y, GLfloat depth);